import sys
import getopt
import urllib2
import webbrowser

import wxversion
wxversion.select(["2.7.2", "2.8"])
import wx
import wx.html

from updater._updater import OpenRPGUpdater
from orpg.tools.settings import settings

class GUIUpdater(OpenRPGUpdater):
    section = None

    def __init__(self, force=False):
        self.frame = UpdaterFrame(None, wx.ID_ANY, "OpenRPG Updater")

        self.frame.Raise()
        self.frame.Refresh()
        self.frame.Show()
        wx.CallAfter(self.check_updates, force)

    def check_updates(self, force=False):
        super(GUIUpdater, self).check_updates()

        if force or (not self.update_done and self.is_update):
            self.section = self.c_section

            self.show_ui()
        else:
            self.frame.Close()

    def show_ui(self):
        self.frame.buttons['current_version'].SetLabel('Current Version %s.%s' % (self.c_version, self.c_revision))
        self.frame.buttons['select_version'].Clear()

        packages = self.remote_packages.find(self.section).getiterator('package')
        versions = {}
        for pkg in packages:
            versions[pkg.get('version')] = pkg

        vk = versions.keys()
        vk.sort()
        vk.reverse()

        self.frame.versions = versions
        self.frame.vk = vk

        i = 0
        for version in vk:
            msg = vk[i] + '.' + versions[vk[i]].get('revision')
            self.frame.buttons['select_version'].Append(msg)
            i += 1

        self.frame.buttons['select_section'].Clear()
        for sec in self.remote_packages.getroot().getchildren():
            self.frame.buttons['select_section'].Append(sec.tag)

        self.frame.buttons['select_section'].SetStringSelection(self.section)


        self.frame.Bind(wx.EVT_BUTTON, self.do_updates, self.frame.buttons['update'])
        self.frame.Bind(wx.EVT_CHOICE, self.update_section,
                  self.frame.buttons['select_section'])
        self.frame.Bind(wx.EVT_CHOICE, self.update_version,
                  self.frame.buttons['select_version'])

        self.frame.buttons['update'].Disable()

    def update_version(self, evt):
        v = self.frame.buttons['select_version'].GetStringSelection()
        version = ".".join(v.split('.')[:3])

        url = 'http://orpgmeta.appspot.com/releasenotes?version=' + version
        try:
            conn = urllib2.urlopen(url)
            self.frame.changelog.SetPage(conn.read())
        except urllib2.HTTPError:
            self.frame.changelog.SetPage("The Release Notes server seems down")
        finally:
            try:
                conn.close()
            except UnboundLocalError:
                pass

        self.build_update_tree(self.section, version)
        self.frame.buttons['update'].Enable()

    def update_section(self, evt):
        self.section = self.frame.buttons['select_section'].GetStringSelection()
        self.show_ui()
        self.frame.buttons['update'].Disable()

    def do_updates(self, evt=None):
        self.frame.buttons['update'].Disable()
        super(GUIUpdater, self).do_updates(wx.Yield)
        self.frame.Close()

    def write(self, msg):
        self.frame.updatelog.Value += msg + "\n"

class NotesHTMLWindow(wx.html.HtmlWindow):
    """Window used to display the Release Notes"""
    def __init__(self, parent):
        wx.html.HtmlWindow.__init__(self, parent, wx.ID_ANY, size=(400, 1))

    def OnLinkClicked( self, ref ):
        """Open an external browser to resolve links!!!"""
        href = ref.GetHref()
        webbrowser.open(href)

class UpdaterFrame(wx.Frame):
    versions = None
    vk = None

    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.Point(100, 100),
                          wx.Size(600,420), style=wx.DEFAULT_FRAME_STYLE)
        self.CenterOnScreen()

        self.panel = wx.Panel(self, wx.ID_ANY)

        sizer = wx.GridBagSizer(hgap=1, vgap=1)

        self.changelog = NotesHTMLWindow(self.panel)
        self.updatelog = wx.TextCtrl(self.panel, wx.ID_ANY,
                                     style=wx.TE_MULTILINE)

        self.buttons = {}
        self.buttons['auto_text'] = wx.StaticText(self.panel, wx.ID_ANY,
                                                  "Full Auto Update")
        self.buttons['auto_check'] = wx.CheckBox(self.panel, wx.ID_ANY)
        self.buttons['fast_text'] = wx.StaticText(self.panel, wx.ID_ANY,
                                                  "Auto Bug Fix Update")
        self.buttons['fast_check'] = wx.CheckBox(self.panel, wx.ID_ANY)
        self.buttons['update'] = wx.Button(self.panel, wx.ID_ANY, "Update Now")
        self.buttons['skip_update'] = wx.Button(self.panel, wx.ID_ANY,
                                                "Skip Update")
        self.buttons['current_version'] = wx.StaticText(self.panel, wx.ID_ANY,
                                                        "Current Version: ")
        self.buttons['version_text'] = wx.StaticText(self.panel, wx.ID_ANY,
                                                     "Version")
        self.buttons['select_version'] = wx.Choice(self.panel, wx.ID_ANY,
                                                   choices=[])
        self.buttons['select_section'] = wx.Choice(self.panel, wx.ID_ANY,
                                                   choices=[])

        self.buttons['select_version'].SetSelection(0)

        sizer.Add(self.changelog, (0,0), span=(1,3), flag=wx.EXPAND)
        sizer.Add(self.updatelog, (0,3), flag=wx.EXPAND)
        sizer.Add(wx.StaticLine(self, wx.ID_ANY, size=wx.Size(600,3)),
                       (1,0), span=(1,4))
        sizer.Add(self.buttons['current_version'], (2,0), flag=wx.EXPAND)
        sizer.Add(self.buttons['select_section'], (3,0))
        sizer.Add(self.buttons['version_text'], (3,1))
        sizer.Add(self.buttons['select_version'], (3,2), flag=wx.EXPAND)
        sizer.Add(self.buttons['auto_text'], (4,0), flag=wx.ALIGN_RIGHT)
        sizer.Add(self.buttons['auto_check'], (4,1))
        sizer.Add(self.buttons['fast_text'], (4,2), flag=wx.ALIGN_RIGHT)
        sizer.Add(self.buttons['fast_check'], (4,3))
        sizer.Add(self.buttons['update'], (5,0), span=(1,3),
                       flag=wx.EXPAND)
        sizer.Add(self.buttons['skip_update'], (5,3), flag=wx.ALIGN_RIGHT)

        sizer.AddGrowableCol(0)
        sizer.AddGrowableCol(3)
        sizer.AddGrowableRow(0)

        fs = wx.BoxSizer(wx.HORIZONTAL)
        fs.Add(self.panel, 1, flag=wx.EXPAND)
        self.SetSizer(fs)
        self.SetAutoLayout(True)
        self.Layout()

        self.panel.SetSizer(sizer)
        self.panel.SetAutoLayout(True)
        self.panel.Layout()

        if settings.get('auto_update').lower() in ('true', 'yes', 'on'):
            self.buttons['auto_check'].SetValue(True)

        if settings.get('fast_update').lower() in ('true', 'yes', 'on'):
            self.buttons['fast_check'].SetValue(True)

        self.Bind(wx.EVT_CHECKBOX, self.ToggleAutoUpdate, self.buttons['auto_check'])
        self.Bind(wx.EVT_CHECKBOX, self.ToggleAutoBugUpdate, self.buttons['fast_check'])
        self.Bind(wx.EVT_BUTTON, self.SkipUpdate, self.buttons['skip_update'])

    def ToggleAutoUpdate(self, event):
        if self.buttons['auto_check'].GetValue():
            settings.set("auto_update", "True")
        else:
            settings.set("auto_update", "False")

    def ToggleAutoBugUpdate(self, event):
        if self.buttons['fast_check'].GetValue():
            settings.set("fast_update", "True")
        else:
            settings.set("fast_update", "False")

    def SkipUpdate(self, evt):
        wx.MessageBox("Skipping updates prevents you fron getting new bug fixes",
                      "Warning!")
        self.Close()

class UpdaterApp(wx.App):
    def OnInit(self):
        return True

if __name__ == "__main__":
    force = False

    (opts, args) = getopt.getopt(sys.argv[1:], "fn:phml:m:d:", ["help",
                                                                "manual",
                                                                "directory="])
    for o, a in opts:
        if o in ('-f', '--force'):
            force = True

    mainapp = UpdaterApp(0)
    updater = GUIUpdater(force)
    mainapp.MainLoop()